/**
 * Created by haoran.shu on 2018/7/31 10:03.
 */

module.exports = {

  /**
   * 生成随机数； 参数 n, m 均为可选参数；根据传递的参数不同返回不同的类型的随机数
   *   1. 参数 n, m 均填, 则如果参数 e = true；则生成 [n, m] 之间的随机数[i = true整形]，否则 [n, m)
   *   2. 如果只填写了 n；则表示生成多少位长度的随机数字符串(首位包括 0)
   * @param n     如果单独只填写了该参数则表示只生成 n 位长度的随机数; 否则表示生成的随机数必须大于等于 n
   * @param m     生成的随机数必须小于(或等于由参数 e 决定) m
   * @param opts  { object }
   *    number:     {boolean} 生成的随机数是整形还是小数形, 仅在有 m 参数时有效; true 表示整形
   *    end:        {boolean} 生成的随机数是否包含末尾数字m; 仅在有 m 参数并且 number = true 时有效; true 表示包含
   *    firstZero:  {boolean} 默认为 true; 当生成 n 位长度的随机数时, 首位是否包含 0; 如果为 true 则返回的格式是字符串类型
   */
  random: function(n, m = void 0, opts) {
    let random = Math.random();
    let o = {}; // 配置
    if(typeof m === 'number') { // 传递了 m 参数
      o = Object.assign({}, opts || {});
      if(o.number === true) {
        if(o.end === true) {
          return parseInt(random * (m - n + 1) + n, 10);
        } else {
          return parseInt(random * (m - n) + n, 10);
        }
      } else {
        return random * (m - n) + n;
      }
    } else { // 没有传递 m 参数; 生成 n 位长度的随机数字符串(首位包括 0)
      o = Object.assign({ firstZero: true }, m || {});
      if(o.firstZero === true) {
        random = random.toString();
        return random.substr(random.indexOf('.') + 1, n);
      } else {
        let max = Math.pow(10, n);
        random = parseInt(random * max, 10);
        if(random < max) { // 生成的随机数前置有0, 重新生成
          return this.random(m, o);
        } else {
          return random;
        }
      }
    }
  },

  /**
   * 使用制定的分隔符拆分 Set 为字符串(类似于 Array.prototype.join)
   * @param set   {Set}
   * @param sep   分隔符, 默认为 ,
   * @return {string}
   */
  setJoin(set, sep) {
    sep = sep || ',';
    let s = '';
    for(let v of set) {
      s+=(sep + v);
    }
    return s.substring(sep.length);
  },

  /**
   * 判断某个对象是否包含(key)集合中的值, 一般用于判断传递的接口是否包含必须的参数
   * @param obj     传递的参数列表
   * @param params  {Array}
   */
  containsParam(obj, params) {
    let k = void 0;
    if(!obj) {
      k = params[0];
      return k;
    }
    for(let p of params) {
      let s = obj[p];
      if(s === undefined || s == null) { // 不包含某个参数
        k = p;
        break; // 跳出循环
      }
    }
    return k;
  },

  /**
   * 数组排序并截取制定的数量的新数组, 会改变原始数组
   * @param arr   原始数组
   * @param order 排序规则, asc || desc
   * @param limit limit number
   * @param key   排序的健, 如果数组包含的是对象，需要这个参数，如果不传, 则默认数组包含的是一个数字或者字符串
   */
  sortLimit(arr, order, limit, key) {
    // 排序
    arr.sort((a, b) => {
      if(key) {
        if(order === 'desc') { // 倒序
          return b[key] - a[key];
        } else { // 顺序
          return a[key] - b[key];
        }
      } else {
        if(order === 'desc') {
          return b - a;
        } else {
          return a - b;
        }
      }
    });
    return arr.slice(0, limit);
  }
};
